/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package matematicadiscretaxml;

import arbol_prueba.BTree;
import java.util.ArrayList;
import javax.swing.JOptionPane;

/**
 *
 * @author diego
 */
public class Insercion {
 
    private ArrayList lista_lexemas = new ArrayList();
    ObjetoQuery tabla_obj_query[][] = new ObjetoQuery[0][0];//TABLA QUE RESULTA DEL PRODUCTO CARTESIANO
    ObjetoQuery tabla_obj_query_foranea[][] = new ObjetoQuery[0][0];//TABLA QUE RESULTA DE LA TABLA FORANEA
    ArrayList<ObjetoQuery> obj_insertar = new ArrayList();

    ArrayList lista_def_columnas = new ArrayList();
    ArrayList lista_errores_insercion = new ArrayList();//GUARDA LOS ERRORES
    int contador_values = 0;

    public Insercion(){}

    public Insercion(ArrayList _lista_lexemas)
    {
        lista_lexemas = _lista_lexemas;
    }

    public void generarArbolSintacticoInsercion()
    {
        Insert obj_insert = new Insert(lista_lexemas);
        Into obj_into = new Into(lista_lexemas);
        Values obj_values = new Values(lista_lexemas);
        BTree sub_arbol_insert = null;
        BTree sub_arbol_values = null;
        BTree sub_arbol_into = null;

        System.out.println("**************************************************************");
        obj_insert.ingresarPilas();
        sub_arbol_insert = obj_insert.generarSubArbolInsert(new BTree("nulo"));
        lista_errores_insercion.addAll(obj_insert.getlista_errores_insert());

        if(lista_errores_insercion.isEmpty())
        {
            sub_arbol_insert.imprimePostOrden();
            System.out.println("**************************************************************");
            obj_into.ingresarPilas();
            sub_arbol_into = obj_into.generarSubArbolInto(new BTree("nulo"));
            lista_errores_insercion.addAll(obj_into.getlista_errores_into());
            if(lista_errores_insercion.isEmpty())
            {
                sub_arbol_into.imprimePostOrden();
                System.out.println("**************************************************************");
                obj_values.ingresarPilas();
                sub_arbol_values = obj_values.generarSubArbolValues(new BTree("nulo"));
                lista_errores_insercion.addAll(obj_values.getlista_errores_values());
                if(lista_errores_insercion.isEmpty())
                {
                    sub_arbol_values.imprimePostOrden();
                    ejecutarInsercion(sub_arbol_insert, sub_arbol_into, sub_arbol_values);
                }
            }
        }
    }

    public void ejecutarInsercion(BTree sub_arbol_insert, BTree sub_arbol_into, BTree sub_arbol_values)
    {
        contador_values = 0;
        recorrerSubArbolInsert(sub_arbol_insert);
        if(lista_errores_insercion.isEmpty())
        {
            recorrerSubArbolInto(sub_arbol_into);
            if(lista_errores_insercion.isEmpty())
            {
                recorrerSubArbolValues(sub_arbol_values);
                if(lista_errores_insercion.isEmpty())
                {
                    if(contador_values == lista_def_columnas.size())
                    {
                        imprimirMatriz(tabla_obj_query);
                        XML obj_xml = new XML("archivos_usados/archivos_base_datos/archivos_datos/"+
                            ((DefinicionTabla)lista_def_columnas.get(0)).getNombre_tabla().toLowerCase()+"_dat.xml");
                        obj_xml.ingresarRegistroXML(obj_insertar);
//                        for(int i = 0; i<obj_insertar.size(); i++)
//                        {
//                            System.out.println(obj_insertar.get(i).getTabla()+" | "+obj_insertar.get(i).getColumna()+" | "+obj_insertar.get(i).getObjeto());
//                        }
//                        System.out.println("");
                    }
                    else
                    {
                        lista_errores_insercion.add(new Error("BLOQUE VALUES", "EL NUMERO DE VALORES INGRESDOS NO CORRESPONDE AL NUMERO DE COLUMNAS DE LA TABLA"));
                    }
                }
                else
                {
                    tabla_obj_query = new ObjetoQuery[0][0];
                }
            }
        }
    }

    public void recorrerSubArbolValues(BTree nodo)
    {
        if( nodo.getIzquierda()!= null )
        {
            recorrerSubArbolValues(nodo.getIzquierda());
        }
        if(nodo.getDerecha() != null)
        {
            recorrerSubArbolValues(nodo.getDerecha());
        }
        if( ((Lexema)nodo.getElement()).getTipo_lexema() == 5
                || ((Lexema)nodo.getElement()).getTipo_lexema() == 6 )
        {
            /*
            * ACA SE DEBE VERIFICAR SI LOS TIPOS DE DATOS DE LAS
            * CONSTANTES INGRESADAS SON CORRECTAS DE ACUERDO AL ARRAYLIST DE lista_def_columnas
            * ADEMAS SE DEBE VERIFICAR SI QUE LA CLAVE PRIMARIA SEA UNICA
            */
            if( nodo.getDerecha() == null
                    && ( nodo.getIzquierda()!= null
                         || nodo.getIzquierda()== null))
            {

                if( ((Lexema)nodo.getElement()).getTipo_lexema() == 5 )
                {
                    if ( !((DefinicionTabla)lista_def_columnas.get(contador_values)).getTipo_dato().equals("varchar") )
                    {
                        lista_errores_insercion.add(new Error("BLOQUE VALUES", "EL TIPO DE DATO INGRESADO NO CORRESPONDE A LA DEFINICION DE LA COLUMNA"));
                    }
                }
                else if ( ((Lexema)nodo.getElement()).getTipo_lexema() == 6 )
                {
                    if ( !((DefinicionTabla)lista_def_columnas.get(contador_values)).getTipo_dato().equals("double") )
                    {
                        lista_errores_insercion.add(new Error("BLOQUE VALUES", "EL TIPO DE DATO INGRESADO NO CORRESPONDE A LA DEFINICION DE LA COLUMNA"));
                    }
                }

                if( ((DefinicionTabla)lista_def_columnas.get(contador_values)).getPrimaria().equals("si") )
                {
                    for(int i = 0; i<tabla_obj_query.length; i++)
                    {
                        if( tabla_obj_query[i][contador_values].getObjeto().toString().equals( ((Lexema)nodo.getElement()).getLexema().replace("'", "") ) )
                        {
                            lista_errores_insercion.add(new Error("BLOQUE VALUES", "LA CLAVE PRIMARIA YA EXISTE"));
                        }
                    }
                }

                ObjetoQuery obj_query = new ObjetoQuery(((DefinicionTabla)lista_def_columnas.get(contador_values)).getNombre_tabla()
                                                        , ((DefinicionTabla)lista_def_columnas.get(contador_values)).getNombre()
                                                        , ((Lexema)nodo.getElement()).getLexema().replace("'", ""));

                obj_insertar.add(obj_query);

                if( ((DefinicionTabla)lista_def_columnas.get(contador_values)).getForanea().equals("si") )
                {
                    Archivo carchivo = new Archivo();
                    carchivo.LeerArchivo("archivos_usados/archivos_base_datos/archivos_definicion/"+
                        ((DefinicionTabla)lista_def_columnas.get(contador_values)).getTabla_referencia().toLowerCase()+"_def.xml");

                    if( !carchivo.getContenido_archivo().isEmpty() )
                    {
                        /*
                         * ACA SE VERIFICA SI LA CLAVE FORANEA EXISTE EN LA TABLA DE REFERENCIA
                         */
                        boolean encontrado_tab_ref = false;

                        XML xml_ = new XML("archivos_usados/archivos_base_datos/archivos_datos/"+
                            ((DefinicionTabla)lista_def_columnas.get(contador_values)).getTabla_referencia().toLowerCase()+"_dat.xml");
                        tabla_obj_query_foranea = xml_.leerArchivosDatos(((DefinicionTabla)lista_def_columnas.get(contador_values)).getTabla_referencia().toLowerCase());
                        imprimirMatriz(tabla_obj_query_foranea);

                        for(int i = 0; i<tabla_obj_query_foranea.length; i++)
                        {
                            for(int j = 0; j<tabla_obj_query_foranea[0].length; j++)
                            {
                                if( tabla_obj_query_foranea[i][j].getColumna().equals(((DefinicionTabla)lista_def_columnas.get(contador_values)).getNombre()) )
                                {
                                    if(tabla_obj_query_foranea[i][j].getObjeto().toString().equals(((Lexema)nodo.getElement()).getLexema().replace("'", "")))
                                    {
                                        encontrado_tab_ref = true;
                                    }
                                }
                            }
                        }
                        if(encontrado_tab_ref == false)
                        {
                            lista_errores_insercion.add(new Error("BLOQUE VALUES", "LA CLAVE FORANEA NO EXISTE EN LA TABLA DE REFERENCIA"));
                        }
                    }
                    else
                    {
                        lista_errores_insercion.add(new Error("BLOQUE VALUES", "LA CLAVE FORANEA INGRESADA NO EXISTE"));
                    }
                }

            }
            else
            {
                lista_errores_insercion.add(new Error("BLOQUE VALUES", "SOLO DEBE CONTENER UN IDENTIFICADOR DE TABLA"));
            }
            contador_values++;
        }
        else if( ((Lexema) nodo.getElement()).getTipo_lexema() == 1
                 && ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals("values")
            )
        {
            if( !(((Lexema)nodo.getDerecha().getElement()).getLexema().equals(")")
                   && ( ((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 2 
                   || ((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 4) ) )
            {
                lista_errores_insercion.add(new Error("BLOQUE VALUES", "NO COMIENZA CON LA PALABRA VALUES"));
            }

        }
        else if( ((Lexema) nodo.getElement()).getTipo_lexema() == 2 )
        {
            if( ((Lexema) nodo.getElement()).getLexema().equals(",") )
            {
                if( !( (   ((Lexema) nodo.getDerecha().getElement()).getTipo_lexema() == 5
                        || ((Lexema) nodo.getDerecha().getElement()).getTipo_lexema() == 6 )
                   &&  ( (   ((Lexema) nodo.getIzquierda().getElement()).getTipo_lexema() == 5
                        || ((Lexema) nodo.getIzquierda().getElement()).getTipo_lexema() == 6 )
                      || ((Lexema) nodo.getIzquierda().getElement()).getTipo_lexema() == 2 ) ) )
                {
                    lista_errores_insercion.add(new Error("BLOQUE VALUES", "LA SENTENCIA VALUES TIENE UN SIMBOLO MAL UBICADO_1"));
                }
            }
            else if ( ((Lexema) nodo.getElement()).getLexema().equals("(")
                    || ((Lexema) nodo.getElement()).getLexema().equals(")") )
            {
                if( !(nodo.getIzquierda() == null
                    && nodo.getDerecha() == null  ))
                {
                    lista_errores_insercion.add(new Error("BLOQUE VALUES", "LA SENTENCIA VALUES TIENE UN SIMBOLO MAL UBICADO_2"));
                }
            }
            else
            {
                lista_errores_insercion.add(new Error("BLOQUE VALUES", "LA SENTENCIA VALUES TIENE UN SIMBOLO MAL UBICADO_3"));
            }
        }
        else
        {
            lista_errores_insercion.add(new Error("BLOQUE VALUES", "TIENE SENTENCIAS MAL INGRESADAS"));
        }
    }


    public void recorrerSubArbolInto(BTree nodo)
    {
        if( nodo.getIzquierda()!= null )
        {
            recorrerSubArbolInto(nodo.getIzquierda());
        }
        if(nodo.getDerecha() != null)
        {
            recorrerSubArbolInto(nodo.getDerecha());
        }
        if(((Lexema)nodo.getElement()).getTipo_lexema() == 4 )
        {
            if( nodo.getDerecha() == null && nodo.getIzquierda() == null)
            {
                Archivo carchivo = new Archivo();
                carchivo.LeerArchivo("archivos_usados/archivos_base_datos/archivos_definicion/"+
                    ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def.xml");

                if( !carchivo.getContenido_archivo().isEmpty() )
                {
                    XML xml_ = new XML("archivos_usados/archivos_base_datos/archivos_definicion/"+
                        ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def.xml");

                    lista_def_columnas = xml_.retornarListaCampos(((Lexema)nodo.getElement()).getLexema().toLowerCase());

                    xml_ = new XML("archivos_usados/archivos_base_datos/archivos_datos/"+
                        ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_dat.xml");
                    tabla_obj_query = xml_.leerArchivosDatos(((Lexema)nodo.getElement()).getLexema().toLowerCase());

                    imprimirMatriz(tabla_obj_query);

                }
                else
                {
                    lista_errores_insercion.add(new Error("BLOQUE INTO", "LA TABLA NO EXISTE"));
                }
            }
            else
            {
                lista_errores_insercion.add(new Error("BLOQUE INTO", "SOLO DEBE CONTENER UN IDENTIFICADOR DE TABLA"));
            }
        }
        else if( ((Lexema) nodo.getElement()).getTipo_lexema() == 1
                 && ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals("into")
            )
        {
            if( !( ((Lexema)nodo.getDerecha().getElement()).getLexema() == null
                    && ((Lexema)nodo.getIzquierda().getElement()).getLexema() != null ))
            {
                lista_errores_insercion.add(new Error("BLOQUE INTO", "NO COMIENZA CON LA PALABRA INTO"));
            }
            
        }
        else if( ((Lexema)nodo.getElement()).getLexema() == null)
        {

        }
        else
        {
            lista_errores_insercion.add(new Error("BLOQUE INTO", "LA SENTENCIA INTO ESTA MAL"));
        }
    }

    public void recorrerSubArbolInsert(BTree nodo)
    {
        if( nodo.getIzquierda()!= null )
        {
            recorrerSubArbolInsert(nodo.getIzquierda());
        }
        if(nodo.getDerecha() != null)
        {
            recorrerSubArbolInsert(nodo.getDerecha());
        }
        if( !(   ((Lexema)nodo.getElement()).getTipo_lexema() == 1
            && ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals("insert")
            && ((Lexema)nodo.getDerecha().getElement()).getLexema() == null
            && ((Lexema)nodo.getIzquierda().getElement()).getLexema() == null ))
        {
            if(((Lexema)nodo.getElement()).getLexema() != null)
            {
                lista_errores_insercion.add(new Error("BLOQUE INSERT", "NO COMIENZA CON LA PALABRA INSERT"));
            }
            
        }
    }


    public void imprimirMatriz(ObjetoQuery[][] matriz)
    {
        System.out.println("*********** SELECCION **************");
        for(int i = 0; i<matriz.length; i++)
        {
            for(int j = 0; j<matriz[0].length; j++)
            {
                System.out.print(matriz[i][j].getObjeto()+" | ");
//                System.out.print(matriz[i][j].getTabla()+"."+matriz[i][j].getColumna()+" | ");
            }
            System.out.println("");
        }
    }


    public void generarVectorDefinicionDatos(BTree nodo, String nombre_tabla)
    {
        if( nodo.getIzquierda()!= null )
        {
            generarVectorDefinicionDatos(nodo.getIzquierda(), nombre_tabla);
        }
        if(nodo.getDerecha() != null)
        {
            generarVectorDefinicionDatos(nodo.getDerecha(), nombre_tabla);
        }

        if( ((Lexema)nodo.getElement()).getTipo_lexema() == 4
                && ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals(nombre_tabla.toLowerCase()))
        {
            Archivo carchivo = new Archivo();
            carchivo.LeerArchivo("archivos_usados/archivos_base_datos/archivos_definicion/"+
                    ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def.xml");

            if( !carchivo.getContenido_archivo().isEmpty() )
            {
                XML xml_ = new XML("archivos_usados/archivos_base_datos/archivos_definicion/"+
                    ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def.xml");

                ArrayList arreglo = xml_.retornarListaCampos(nombre_tabla);

                for (int i = 0; i < arreglo.size(); i++ )
                {
                    System.out.println("ATRIBUTO: "+ ((DefinicionTabla)arreglo.get(i)).getNombre_tabla() +" | "
                                                    + ((DefinicionTabla)arreglo.get(i)).getNombre() +" | "
                                                    + ((DefinicionTabla)arreglo.get(i)).getTipo_dato() +" | "
                                                    + ((DefinicionTabla)arreglo.get(i)).getPrimaria() +" | "
                                                    + ((DefinicionTabla)arreglo.get(i)).getForanea() +" | "
                                                    + ((DefinicionTabla)arreglo.get(i)).getTabla_referencia() +" | ");
                }
            }
            else
            {
                System.out.println("EL ARCHIVO "+((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def NO EXISTE");
            }
        }
//        return num_repitencias_campo;
    }

    public int buscarCamposEnArbolFrom(BTree nodo, String nombre_campo)
    {
        int num_repitencias_campo = 0;

        if( nodo.getIzquierda()!= null )
        {
            num_repitencias_campo = num_repitencias_campo + buscarCamposEnArbolFrom(nodo.getIzquierda(), nombre_campo);
        }
        if(nodo.getDerecha() != null)
        {
            num_repitencias_campo = num_repitencias_campo + buscarCamposEnArbolFrom(nodo.getDerecha(), nombre_campo);
        }

        if( ((Lexema)nodo.getElement()).getTipo_lexema() == 4 )
        {
            Archivo carchivo = new Archivo();
            carchivo.LeerArchivo("archivos_usados/archivos_base_datos/archivos_definicion/"+
                    ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def.xml");

            if( !carchivo.getContenido_archivo().isEmpty() )
            {
                XML xml_ = new XML("archivos_usados/archivos_base_datos/archivos_definicion/"+
                    ((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def.xml");
                ArrayList arreglo = xml_.leerXMLArchivos("campo", "nombre");

                for (int i = 0; i < arreglo.size(); i++ )
                {
                    if(arreglo.get(i).toString().toLowerCase().equals(nombre_campo.toLowerCase()))
                    {
                        num_repitencias_campo = num_repitencias_campo + 1;
                    }
                }
            }
            else
            {
                System.out.println("EL ARCHIVO "+((Lexema)nodo.getElement()).getLexema().toLowerCase()+"_def NO EXISTE");
            }
        }
        return num_repitencias_campo;
    }

    /**
     * @return the lista_lexemas
     */
    public ArrayList getLista_lexemas() {
        return lista_lexemas;
    }

    /**
     * @param lista_lexemas the lista_lexemas to set
     */
    public void setLista_lexemas(ArrayList lista_lexemas) {
        this.lista_lexemas = lista_lexemas;
    }

}
